package cn.yunbamboos.media.zlm;

import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.system.SystemUtil;
import cn.yunbamboos.media.zlm.client.ZLMClient;
import cn.yunbamboos.media.zlm.config.ZLMConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

/**
 * 本地的ZLMediaKitServer服务
 * 通过ProcessBuilder启动本地的ZLMediaKit服务
 */
public class LocalZLMediaKitServer implements DisposableBean {

    private static final Logger logger = LoggerFactory.getLogger(LocalZLMediaKitServer.class);

    private final ZLMClient client;

    private Process process;
    private Thread thread;

    public LocalZLMediaKitServer(ZLMClient client) {
        this.client = client;
    }

    public void run() {
        try {
            ZLMConfig config = client.getConfig();
            config.writeConfigIni();

            List<String> command = buildCmd();
            logger.info("[ZLMediaKit] 启动 cmd: {}", StrUtil.join(" ", command));
            ProcessBuilder builder = new ProcessBuilder(command);
            builder.redirectErrorStream(true);
            process = builder.start();
            InputStream input = process.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(input));
            String line;
            while ((line = reader.readLine()) != null) {
                if (logger.isTraceEnabled()) {
                    logger.trace("[ZLMediaKit] {}", line);
                }
                if (Thread.currentThread().isInterrupted()) {
                    logger.info("[ZLMediaKit] 停止");
                    break;
                }
            }
            // 等待进程结束并获取退出值
            int exitCode = process.waitFor();
            logger.info("[ZLMediaKit] 停止 exit code: {}", exitCode);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        } finally {
            if (process != null) {
                process.destroy();
            }
        }
    }

    private List<String> buildCmd() {
        List<String> command = new ArrayList<>();
        if(SystemUtil.getOsInfo().isWindows()){
            command.add(client.getDir()+ "MediaServer.exe");
        } else {
            command.add(client.getDir()+ "MediaServer");
        }
        return command;
    }

    public boolean isRunning() {
        return !ObjUtil.isNull(process) && process.isAlive();
    }

    public void start() {
        thread = new Thread(this::run, "ZLMediaKit");
        thread.start();
    }

    public void stop() {
        if (!ObjUtil.isNull(process)) {
            process.destroy();
        }
    }

    @Override
    public void destroy() throws Exception {
        stop();
    }
}
